Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable cross-compilation between both Darwin platforms #256590

Closed
wants to merge 151 commits into from

Conversation

reckenrode
Copy link
Contributor

@reckenrode reckenrode commented Sep 21, 2023

Description of changes

While cross-compilation from x86_64-darwin to aarch64-darwin already works, going the other way runs into issues with the source-based SDK. This PR resolves those issues and enables cross-compilation to x86_64-darwin. It should now be possible to build any of the following scenarios from a Darwin host:

  • aarch64-darwin native (dynamic and static)
  • x86-darwin native (dynamic and static)
  • aarch64-darwin to x86_64-darwin (dynamic and static)
  • x86_64-darwin to aarch64-darwin (dynamic and static)

I have tried to keep the changes required small and limited. While working on this PR, I found a few derivations that did not build correctly when cross-compiling. Fixing those was outside the scope of this PR unless they were required by the bootstrap or are part of the cross-stdenv.

Known breakage: brotli (references a dylib from the build environment), Wine (has a buildInput in one of its phase scripts), DarwinTools (needs modifications for cross-compilation). MoltenVK is probably also broken.

Regarding Linux: I briefly looked at whether this would work on Linux. There’s work needing to be done to make certain required tools like bootstrap_cmds work on Linux. Expanding cross-compilation to Linux is outside the scope of this PR.

Note: My tests were done using my clang 16 branch. I have successfully evaluated the clang 11 branch used for this PR, but it will take overnight to build. I wanted to open this PR to get it out there for review, so I am opening it as a draft. If all goes well, I’ll flip this to ready tomorrow (Friday, 2023-09-22).

Resolved Issues

This PR should close the following issues:

Prerequisite PRs

Related PRs

Things done

  • Built on platform(s)
    • x86_64-linux
    • aarch64-linux
    • x86_64-darwin
    • aarch64-darwin
  • For non-Linux: Is sandbox = true set in nix.conf? (See Nix manual)
  • Tested, as applicable:
  • Tested compilation of all packages that depend on this change using nix-shell -p nixpkgs-review --run "nixpkgs-review rev HEAD". Note: all changes have to be committed, also see nixpkgs-review usage
  • Tested basic functionality of all binary files (usually in ./result/bin/)
  • 23.11 Release Notes (or backporting 23.05 Release notes)
    • (Package updates) Added a release notes entry if the change is major or breaking
    • (Module updates) Added a release notes entry if the change is significant
    • (Module addition) Added a release notes entry if adding a new NixOS module
  • Fits CONTRIBUTING.md.

@reckenrode
Copy link
Contributor Author

The LLVM 11 build failed in compiler-rt on aarch64-darwin. I could have reverted back to #123524, but it would be really nice to have parity between both architectures. Fortunately, I was able to fix it by backporting some of the changes from the compiler-rt 16 derivation. It’s building again, and hopefully it should finish by this evening.

Strum355 added a commit to sourcegraph/sourcegraph-public-snapshot that referenced this pull request Sep 22, 2023
…es (#56959)

We want to get newer stuff in the devshell, but keep a stabler pin for the static binaries (until darwin stdenv stabilizes, most notably the big brain work over at NixOS/nixpkgs#256590)

## Test plan

N/A nix stuff :clueless:
@reckenrode reckenrode marked this pull request as ready for review September 22, 2023 20:51
@reckenrode reckenrode requested a review from a user September 22, 2023 20:51
@reckenrode
Copy link
Contributor Author

The clang 11 builds completed successfully after I added the fix for compiler-rt. Setting this to ready to review.

Copy link
Contributor

@toonn toonn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly have minor remarks and questions due to unfamiliarity.

Awesome work once again! ❤️

pkgs/development/compilers/llvm/11/default.nix Outdated Show resolved Hide resolved
pkgs/development/compilers/llvm/11/default.nix Outdated Show resolved Hide resolved
pkgs/development/compilers/llvm/11/default.nix Outdated Show resolved Hide resolved
pkgs/development/compilers/llvm/16/compiler-rt/default.nix Outdated Show resolved Hide resolved
pkgs/development/compilers/llvm/16/default.nix Outdated Show resolved Hide resolved
pkgs/os-specific/darwin/swift-corelibs/corefoundation.nix Outdated Show resolved Hide resolved
pkgs/stdenv/adapters.nix Show resolved Hide resolved
pkgs/stdenv/darwin/default.nix Show resolved Hide resolved
@reckenrode
Copy link
Contributor Author

@toonn I believe I’ve addressed all the feedback. I tested static and dynamic cross builds to both x86_64-darwin and aarch64-darwin. I also confirmed Wine builds with the clang 16 stdenv (it does not build with the clang 11 one currently).

@Et7f3
Copy link
Contributor

Et7f3 commented Oct 8, 2023

darwin-cross is at commit a8d8c7640fa324fca6c24ebd0ea7660957a2e556

nix build 'git+file:.?ref=darwin-cross#pkgsCross.aarch64-darwin.darwin.binutils-unwrapped' from x86_64-darwin with sandbox enabled wasn't able to build. At least two derivation failed.

nix log 'git+file:.?ref=darwin-cross#pkgsCross.aarch64-darwin.python3' > pkgsCross.aarch64-darwin.python3.log
nix log 'git+file:.?ref=darwin-cross#pkgsCross.aarch64-darwin.llvm' > pkgsCross.aarch64-darwin.llvm.log

pkgsCross.aarch64-darwin.llvm.log
pkgsCross.aarch64-darwin.python3.log expected behavior python/cpython#90905

pkgsCross.aarch64-darwin.libcxx is fixed with this PR 👍🏻 The llvm error seems to be solvable.
What solved is this change https://github.com/NixOS/nixpkgs/pull/256590/files#diff-dd802e439c9a73b6ade217547e77e33986a0dcf332d0c61337aead7e6ba1f1b2L89-R89

@nixos-discourse
Copy link

This pull request has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/nix-macos-monthly/12330/42

@reckenrode
Copy link
Contributor Author

darwin-cross is at commit a8d8c76

nix build 'git+file:.?ref=darwin-cross#pkgsCross.aarch64-darwin.darwin.binutils-unwrapped' from x86_64-darwin with sandbox enabled wasn't able to build. At least two derivation failed.

nix log 'git+file:.?ref=darwin-cross#pkgsCross.aarch64-darwin.python3' > pkgsCross.aarch64-darwin.python3.log nix log 'git+file:.?ref=darwin-cross#pkgsCross.aarch64-darwin.llvm' > pkgsCross.aarch64-darwin.llvm.log

pkgsCross.aarch64-darwin.llvm.log pkgsCross.aarch64-darwin.python3.log expected behavior python/cpython#90905

pkgsCross.aarch64-darwin.libcxx is fixed with this PR 👍🏻 The llvm error seems to be solvable. What solved is this change https://github.com/NixOS/nixpkgs/pull/256590/files#diff-dd802e439c9a73b6ade217547e77e33986a0dcf332d0c61337aead7e6ba1f1b2L89-R89

I finally got a chance to dig into the LLVM issue. I’ve been testing on my clang 16 branch, so I had to rebuild this branch for clang 11 to test and confirm, and that took a little bit. This is the issue.

"-DCMAKE_C_COMPILER=${nativeCC}/bin/${nativeCC.targetPrefix}cc"
"-DCMAKE_CXX_COMPILER=${nativeCC}/bin/${nativeCC.targetPrefix}c++"
"-DCMAKE_AR=${nativeBintools}/bin/${nativeBintools.targetPrefix}ar"
"-DCMAKE_STRIP=${nativeBintools}/bin/${nativeBintools.targetPrefix}strip"
"-DCMAKE_RANLIB=${nativeBintools}/bin/${nativeBintools.targetPrefix}ranlib"

LLVM needs a native compiler when doing a cross build. That is set up correctly, but the native compiler also needs certain dependencies propagated to it (such as the path to libc++abi.dylib), which does not happen. I have a patch for that, but since cross-compiling LLVM itself is not strictly necessary, it’s out of scope for this PR.

However, I do have a patch, but I want to make sure it applies and works across all of the LLVM versions. I’ll submit the PR (probably tomorrow morning EDT) for it once those finish building (for both aarch64-darwin and x86_64-darwin cross).

@reckenrode
Copy link
Contributor Author

reckenrode commented Oct 11, 2023

I opened #260543 for the LLVM cross-compilation fix.

* Always use `stdenvNoCC` to build Libsystem. This is needed to prevent
  an infinite recursion when cross-building Libsystem;
* Drop ncurses from Libsystem. While upstream does ship ncurses headers,
  everything in nixpkgs should be using ncurses from nixpkgs and not
  using upstream’s headers. This fixes an infinite recursion because
  ncurses still needs to be build to produce an ncurses^dev output;
* Allow the stubs to be conditionally included in Libsystem. This is
  needed to build a bootstrap stdenv for building libresolv and Csu;
* Symlink libresolv instead of copying it into Libsystem’s output. It’s
  not clear why this is necessary anymore, and using a stdenv with
  `install_name_tool` causes an infinite recursion when cross-building.
* Break an infinite recursion by determining the target prefix from
  the platform config. Referencing `stdenv.cc.bintools.targetPrefix`
  causes an infinite recursion because xnu is a dependency of Libsystem;
* Add the host compiler as a dependency for the headers-only build,
  which needs to build tools it will use at build time; and
* Add `migcc`, which provides a target compiler for use with `mig`,
  which needs to invoke clang for the target system during the build.
Break an infinite recursion with CF due to its depending on libc++ and compiler-rt.
With the infinite recursion broken when including darwin.CF in the
stdenv, both regular cross and static builds can use the same
`extraBuildInputs` override.
This ensures it is properly dropped when cross-compiling.
abseil-cpp will try to build for both architectures on Darwin. Not sure
why this works with clang 16, but clang 18 fails when x86_64 flags are
used when building for aarch64-darwin.
b2 tries to invoke the linker without a prefix, which fails.
The http-parser `Makefile` excepts the variable to be `PLATFORM`. Otherwise, it runs `uname -s` and detects the wrong target platform when cross-compiling to Linux from Darwin.
libpsl needs to link against gettext, which requires it be included as a build input even if gettext is already propagated as a native build input.
Actual static builds using `-static` are not supported, but Darwin can still do mostly static.
@ofborg ofborg bot removed the 2.status: merge conflict This PR has merge conflicts with the target branch label May 31, 2024
wolfgangwalther added a commit to wolfgangwalther/postgrest that referenced this pull request May 31, 2024
@reckenrode reckenrode mentioned this pull request Jul 1, 2024
13 tasks
@wegank wegank added the 2.status: merge conflict This PR has merge conflicts with the target branch label Jul 4, 2024
@reckenrode
Copy link
Contributor Author

Sorry about not updating, but this PR will be replaced by the Darwin refactor. I have a replacement for the SDKs that makes using them much easier in Darwin. I am developing it with cross-compilation in mind, so it should just work. This work is targeted for 24.11.

@Mindavi
Copy link
Contributor

Mindavi commented Aug 13, 2024

Thanks for your hard work on that. I think we can close this then, for now.

@Mindavi Mindavi closed this Aug 13, 2024
@will
Copy link
Contributor

will commented Aug 13, 2024

Sorry about not updating, but this PR will be replaced by the Darwin refactor. I have a replacement for the SDKs that makes using them much easier in Darwin. I am developing it with cross-compilation in mind, so it should just work. This work is targeted for 24.11.

Is there a link to somewhere (pr, or message board thread, or anything) to follow along with this? Just curious to see what's going on

@reckenrode
Copy link
Contributor Author

Is there a link to somewhere (pr, or message board thread, or anything) to follow along with this? Just curious to see what's going on

Discussions have been happening on Matrix and in other PRs. I discuss it some in #242666 (comment). To help explain further and provide some background, I created a thread on Discourse: https://discourse.nixos.org/t/on-the-future-of-darwin-sdks-or-how-you-can-stop-worrying-and-put-the-sdk-in-build-inputs/50574

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
2.status: merge conflict This PR has merge conflicts with the target branch 6.topic: cross-compilation Building packages on a different platform than they will be used on 6.topic: darwin Running or building packages on Darwin 6.topic: haskell 6.topic: nodejs 6.topic: python 6.topic: qt/kde 6.topic: ruby 6.topic: stdenv Standard environment 6.topic: vim 8.has: package (new) This PR adds a new package 10.rebuild-darwin: 501+ 10.rebuild-darwin: 5001+ 10.rebuild-darwin-stdenv This PR causes stdenv to rebuild 10.rebuild-linux: 1-10
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants